#ifndef MAILER_P_H
#define MAILER_P_H

#include <QtCore/QRegExp>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QThread>
#include <QtCore/QMutex>
#include <QtSql/QSqlDatabase>
#include "global.h"
#include "dbmanager/sql_query.h"

namespace smsrouter {

class Mailer;

class MailerPrivate : public QObject {
  Q_OBJECT
public:
  MailerPrivate(Mailer *parent);

  virtual ~MailerPrivate();

  struct SrcDeliverUpdateDirections {
    QString state;
    QString next_delivery_date;
    QString attempt;
    QString error_code;
    QString message_state;
    QString where;
  };

  struct SrcDeliverUpdateMessages {
    QString type;
    QString next_delivery_date;
    QString final_date;
    QString attempt;
    QString error_code;
    QString message_state;
    QString where;
  };

  struct DestSubmitUpdateDirections {
    QString state;
    QString dest_message_id;
    QString receive_date;
    QString next_delivery_date;
    QString attempt;
    QString error_code;
    QString message_state;
    QString src_addr_ton_before;
    QString src_addr_npi_before;
    QString src_addr_before;
    QString src_addr_ton_after;
    QString src_addr_npi_after;
    QString src_addr_after;
    QString dest_addr_ton_before;
    QString dest_addr_npi_before;
    QString dest_addr_before;
    QString dest_addr_ton_after;
    QString dest_addr_npi_after;
    QString dest_addr_after;
    QString sm_length;
    QString short_message;
    QString where;
  };

  struct DestSubmitUpdateMessages {
    QString type;
    QString dest_message_id;
    QString next_delivery_date;
    QString final_date;
    QString attempt;
    QString error_code;
    QString message_state;
    QString where;
  };

  struct DestDeliverUpdateDirections {
    QString receive_date;
    QString next_delivery_date;
    QString error_code;
    QString message_state;
    QString src_addr_ton_before;
    QString src_addr_npi_before;
    QString src_addr_before;
    QString src_addr_ton_after;
    QString src_addr_npi_after;
    QString src_addr_after;
    QString dest_addr_ton_before;
    QString dest_addr_npi_before;
    QString dest_addr_before;
    QString dest_addr_ton_after;
    QString dest_addr_npi_after;
    QString dest_addr_after;
    QString sm_length;
    QString short_message;
    QString where;
  };

  Mailer *parent;

  QList<dbmanager::SqlQuery *> queries;

  QThread *thread;

  State state;

  QList<SrcSubmitSm *> wr_src_submit_messages;
  QList<SrcDeliverSm *> wr_src_deliver_messages;
  QList<DestSubmitSm *> wr_dest_submit_messages;
  QList<DestDeliverSm *> wr_dest_deliver_messages;

  QList<SrcDeliverSm *> rd_src_deliver_messages;
  QList<DestSubmitSm *> rd_dest_submit_messages;

  QHash<dbmanager::SqlQuery *, QList<DestSubmitSm *> *>
    query_dest_submit_messages;

  QHash<dbmanager::SqlQuery *, QList<DestDeliverSm *> *>
    query_dest_deliver_messages;

  dbmanager::SqlQuery *rd_dest_submit_query;
  dbmanager::SqlQuery *rd_src_deliver_query;

  int max_write_src_submit;

  int max_write_src_deliver;

  int max_write_dest_submit;

  int max_write_dest_deliver;

  int max_read_dest_submit;

  int max_read_src_deliver;

  int proc_timer;
  int proc_time;

  friend class Mailer;

protected:

  void timerEvent(QTimerEvent *event);

signals:

  void sigStop();

  void sigAdd(SrcSubmitSm *);

  void sigAdd(DestSubmitSm *);

  void sigAdd(DestDeliverSm *);

  void sigAdd(SrcDeliverSm *);

private slots:

  void threadStarted();

  void stop();

  void add(SrcSubmitSm *);

  void add(DestSubmitSm *);

  void add(DestDeliverSm *);

  void add(SrcDeliverSm *);

  void writeSrcSubmit();

  void writeSrcDeliver();

  void writeDestSubmit();

  void writeDestDeliver();

  void readDestSubmit();

  void readSrcDeliver();

  void writeSrcSubmitDirectionsExecuted();

  void writeSrcSubmitMessagesExecuted();

  void writeSrcDeliverDirectionsExecuted();

  void writeSrcDeliverMessagesExecuted();

  void writeDestSubmitDirectionsExecuted();

  void writeDestSubmitMessagesExecuted();

  void selectDestDeliverExecuted();

  void writeDestDeliverDirectionsExecuted();

  void writeDestDeliverMessagesExecuted();

  void readDestSubmitExecuted();

  void readSrcDeliverExecuted();

  void updateDestSubmitExecuted();

  void updateSrcDeliverExecuted();

private:

  bool isReadDestSubmitDb(quint32 dest_session_id, quint32 dest_message_id);

  void checkInitAndStart();

  void checkState();

  void setState(State state);
};

} // namespace smsrouter

#endif // MAILER_P_H
